#include "Cell.h"

#include <iostream>

#include "CatanClassContractException.h"

namespace catan
{

/*static*/ bool Cell::canInit(CellCoordinate cellCoordinate, CellType cellType, CellNumber cellNumber)
{
	bool isSeaCell = Cell::isSea(cellCoordinate);
	switch (cellType.getEnum())
	{
	case CellType::DESERT_TYPE:
		if (isSeaCell)
		{
			return false;  // Land coordinate expected
		}
		if (!(cellNumber == catan::n7_Desert))
		{
			return false;  // Deserts must be assigned 7
		}
		break;
	case CellType::FOREST_TYPE:
	case CellType::PASTURE_TYPE:
	case CellType::FIELDS_TYPE:
	case CellType::HILLS_TYPE:
	case CellType::MOUNTAINS_TYPE:
		if (isSeaCell)
		{
			return false;  // Land coordinate expected
		}
		if (cellNumber == catan::nSea || cellNumber == catan::n7_Desert)
		{
			return false;  // Non-desert land must be assigned a number between 2 to 12 excluding 7
		}
		break;
	case CellType::OPEN_SEA_TYPE:
	case CellType::GENERAL_HARBOR_TYPE:
	case CellType::WOOD_HARBOR_TYPE:
	case CellType::SHEEP_HARBOR_TYPE:
	case CellType::WHEAT_HARBOR_TYPE:
	case CellType::BRICK_HARBOR_TYPE:
	case CellType::ORE_HARBOR_TYPE:
		if (!isSeaCell)
		{
			return false;  // Sea coordinate expected
		}
		if (!(cellNumber == catan::nSea))
		{
			return false;  // Sea must not be assigned any rollable number 
		}
		break;
	default:
		return false;  // Should be impossible to reach here
	}
	return true;
}

/*static*/ bool Cell::isSea(CellCoordinate cellCoordinate)
{
	bool isMapCR = cellCoordinate.isOnGameMapEdge(catan::horizontalCR);
	bool isMapTR = cellCoordinate.isOnGameMapEdge(catan::horizontalTR);
	bool isMapTL = cellCoordinate.isOnGameMapEdge(catan::horizontalTL);
	bool isMapCL = cellCoordinate.isOnGameMapEdge(catan::horizontalCL);
	bool isMapBL = cellCoordinate.isOnGameMapEdge(catan::horizontalBL);
	bool isMapBR = cellCoordinate.isOnGameMapEdge(catan::horizontalBR);

	return (isMapCR || isMapTR || isMapTL || isMapCL || isMapBL || isMapBR);
}

/*static*/ bool Cell::isLand(CellCoordinate cellCoordinate)
{
	return !Cell::isSea(cellCoordinate);
}

Cell::Cell(CellCoordinate cellCoordinate, CellType cellType, CellNumber cellNumber): cellCoordinate(cellCoordinate), cellType(cellType), cellNumber(cellNumber)
{
	if (!Cell::canInit(cellCoordinate, cellType, cellNumber))
	{
		throw CatanClassContractException(__FILE__, __LINE__, "Cell::canInit(...) with constructor arguments should be true before creating instance.");
	}
}

CellCoordinate Cell::getCoordinate() const
{
	return cellCoordinate;
}

CellType Cell::getType() const
{
	return cellType;
}

CellNumber Cell::getNumber() const
{
	return cellNumber;
}

}
